package com.base.lock.redis.shouer;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;



@Component
public class RedisLocker implements DistributedLocker{

	private final static String LOCKER_PREFIX = "lock:";
    /**10分钟 等待获取锁的时间，如果超时，则返回false，如果获取到锁，返回true*/
    public final static int LOCKER_WORKER_DEFULT_TIME = 600;

    @Autowired
    RedissonClient redissonClient;
    
    @Override
    public <T> T tryLock(String key, AquiredLockWorker<T> worker) {
    	return tryLock(key, worker,LOCKER_WORKER_DEFULT_TIME);
    }
    
    @Override
    public <T> T tryLock(String key, AquiredLockWorker<T> worker,int waitTime) {
    	RLock lock = redissonClient.getLock(LOCKER_PREFIX + key);
    	boolean success;
    	try {
    		success = lock.tryLock(waitTime, TimeUnit.SECONDS);
    	} catch (InterruptedException e) {
    		throw new UnableToAquireLockException("999999",e.getMessage(),e);
    	}
    	
    	if (success) {
    		try {
    			return worker.invokeAfterLockAquire();
    		} finally {
    			lock.unlock();
    		}
    	} 
    	throw new UnableToAquireLockException("999999","未获取到锁");
    }

	@Override
	public boolean tryLock(String key) {
		return tryLock(key, LOCKER_WORKER_DEFULT_TIME);
	}

	
	@Override
	public boolean tryLock(String key, int waitTime) {
		RLock lock = redissonClient.getLock(LOCKER_PREFIX + key);
		try {
			return lock.tryLock(waitTime, TimeUnit.SECONDS);
    	} catch (InterruptedException e) {
    		throw new UnableToAquireLockException("999999",e.getMessage(),e);
    	}
	}
	
	@Override
	public void lock(String key) {
		RLock lock = redissonClient.getLock(LOCKER_PREFIX + key);
		lock.lock();
	}

	@Override
	public void unLock(String key) {
		RLock lock = redissonClient.getLock(LOCKER_PREFIX + key);
		if(lock != null && lock.isLocked()) {
			lock.unlock();
		}
	}
    
}
